package com.xiaochong.tir.apiservice.component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xc.logclient.utils.LogTrace;
import com.xiaochong.tir.apiservice.component.hbase.CurrencyInfoHbaseComponent;
import com.xiaochong.service.common.config.redis.RedisServer;
import com.xiaochong.tir.common.data.Bo.CurrencyGainPriceRedisBo;
import com.xiaochong.tir.common.data.hbasepo.CmcCurrencyInfo;
import com.xiaochong.tir.common.data.hbasepo.DailyComprehensiveAnalysisInfo;
import com.xiaochong.tir.common.data.mapper.CurrencyConceptCategoryMapper;
import com.xiaochong.tir.common.data.mapper.CurrencyInfoHbaseMapper;
import com.xiaochong.tir.common.data.mapper.CurrencyInfoMapper;
import com.xiaochong.tir.common.data.po.CurrencyConceptCategory;
import com.xiaochong.tir.common.data.po.CurrencyInfo;
import com.xiaochong.tir.common.data.po.CurrencyInfoHbase;
import com.xiaochong.tir.common.exception.ErrorDataException;
import com.xiaochong.tir.common.util.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 缓存初始化
 * Created by cx on 2018/5/4.
 */
@Component
public class RedisCacheComponent {

    @Autowired
    private CurrencyInfoMapper currencyInfoDao;
    @Autowired
    private RedisServer redisServer;
    @Autowired
    private CurrencyInfoHbaseMapper currencyInfoHbaseMapper;

    @Autowired
    private CurrencyConceptCategoryMapper currencyConceptCategoryMapper;

    @Resource
    private CoinMarketCapDataComponent coinMarketCapDataComponent;
    @Resource
    private CurrencyInfoHbaseComponent currencyInfoHbaseComponent;
    @Resource
    private CmcDataCalculateComponent cmcDataCalculateComponent;
    @Autowired
    private OssImageUtil ossImageUtil;




    /**
     * 货币缓存 初始化
     */
    public List<CurrencyInfo> currencyInit(){
        List<CurrencyInfo> currencyInfoList = currencyInfoDao.selectByEntityList(new CurrencyInfo().setDeleteFlag(false).setEnableFlag(true));
        currencyInfoList.forEach(currencyInfo -> {
            if(StringUtils.isNotBlank(currencyInfo.getCmcId())){
                currencyInfo.setImageUrl(ossImageUtil.fmtImg(currencyInfo.getImageUrl()));

                if(currencyInfo.getWeights()){
                    redisServer.hashSet(RedisKeysUtils.CURRENCY_WEIGHTS_KEY,currencyInfo.getCmcId(),JSONObject.toJSONString(currencyInfo));
                }
                redisServer.hashSet(RedisKeysUtils.CURRENCY_INFO_KEY,currencyInfo.getCmcId(), JSONObject.toJSONString(currencyInfo));
            }
        });
        return currencyInfoList;
    }

    /**
     * 获取所有 货币信息
     * @return
     */
    public List<CurrencyInfo> getCurrencyList(){
       try{
           Map<String,String> currencyStringMap = redisServer.hashEntries(RedisKeysUtils.CURRENCY_INFO_KEY);;
           List<CurrencyInfo> currencyInfoList = new ArrayList<>();
           if(CollectionUtil.isNotBlank(currencyStringMap)){
               for(Map.Entry<String,String> map :currencyStringMap.entrySet()){
                   currencyInfoList.add(JSON.parseObject(map.getValue(),CurrencyInfo.class));
               }
               return currencyInfoList;
           }else{
               List<CurrencyInfo>  currencyList = currencyInit();
               return currencyList;
           }
       }catch (Exception e){
           LogTrace.error("redis连接异常",e);
           return null;
       }
    }

    /**
     * 获取所有 诊断货币信息
     * @return
     */
    public List<CurrencyInfo> getDiagnosisCurrencyList(){
        List<CurrencyInfo> currencyList = this.getCurrencyList();
        if(CollectionUtil.isBlank(currencyList)){
            return null;
        }
        List<CurrencyInfo> resultList = new ArrayList<>();
        for (CurrencyInfo currencyInfo:currencyList) {
            if(currencyInfo.getCurrencyDiagnosisFlag()!=null && currencyInfo.getCurrencyDiagnosisFlag()){
                resultList.add(currencyInfo);
            }
        }
        return resultList;
    }

    /**
     * 根据cmsId获取 货币信息
     * @param cmsId
     * @return
     */
    public CurrencyInfo getCurrencyInfo(String cmsId){
        try{
            String currencyInfo = redisServer.hashGet(RedisKeysUtils.CURRENCY_INFO_KEY,cmsId);
            if(StringUtils.isNotBlank(currencyInfo)){
                return JSONObject.parseObject(currencyInfo,CurrencyInfo.class);
            }
            currencyInit();
        }catch (Exception e){
          LogTrace.error("redi获取连接超时:","cmcId",cmsId,e);
        }

        return currencyInfoDao.selectByEntity(new CurrencyInfo().setCmcId(cmsId));

    }

    /**
     * 获取所有的权重货币
     * @return
     */
    public List<CurrencyInfo> getWeightsCurrencyList(){
        try{
            Map<String,String> currencyStringList = redisServer.hashEntries(RedisKeysUtils.CURRENCY_WEIGHTS_KEY);
            List<CurrencyInfo> currencyInfoList = new ArrayList<>();
            if(CollectionUtil.isNotBlank(currencyInfoList)){
                for(Map.Entry<String,String> map : currencyStringList.entrySet()){
                    currencyInfoList.add(JSONObject.parseObject(map.getValue(),CurrencyInfo.class));
                }
                return currencyInfoList;
            }
            currencyInit();
        }catch (Exception e){
          LogTrace.error("获取所有的权重货币redi获取连接超时:",e);
        }

        return currencyInfoDao.selectByEntityList(new CurrencyInfo().setDeleteFlag(false).setEnableFlag(true).setWeights(true));
    }

    /**
     * 获取单个权重货币
     * @param cmsId
     * @return
     */
    public CurrencyInfo getWeightsCurrencyInfo(String cmsId){
        try{
            String currencyInfo = redisServer.hashGet(RedisKeysUtils.CURRENCY_WEIGHTS_KEY,cmsId);
            if(StringUtils.isNotBlank(currencyInfo)){
                return JSONObject.parseObject(currencyInfo,CurrencyInfo.class);
            }
            currencyInit();
        }catch (Exception e){
           LogTrace.error("获取单个权重货币","获取单个权重货币:",cmsId,e);
        }

        return currencyInfoDao.selectByEntity(new CurrencyInfo().setCmcId(cmsId));
    }

    /**
     * 根据基期
     * @return
     */
    public Date getCurrencyInfoHbaseMinCreateTime(){
        String dateString = redisServer.get(RedisKeysUtils.CURRENCYINFO_HBASE_MIN_CREATETIME);
        Date date = null;
        if(StringUtils.isNotBlank(dateString)){
            try{
                date = new Date(Long.valueOf(dateString));
            }catch (Exception e){
                e.printStackTrace();
                LogTrace.error(e.getMessage(),e);
            }
        }
        if(date==null){
            date = currencyInfoHbaseMapper.selectMaxMinCreateTime("asc");
        }
        redisServer.set(RedisKeysUtils.CURRENCYINFO_HBASE_MIN_CREATETIME,date.getTime());
        return date;
    }


    /**
     * 设置 货币最新的价格以及涨幅
     * @param currencyGainPriceRedisBoList
     */
    public void setCurrencyGainPriceRedisBo(List<CurrencyGainPriceRedisBo> currencyGainPriceRedisBoList){
        currencyGainPriceRedisBoList.forEach(currency ->{
            redisServer.hashSet(RedisKeysUtils.NEW_CURRENCY_GAIN_PRICE_KEY,currency.getCmcId(),JSONObject.toJSONString(currency));
        });

    }

    public List<CurrencyInfo> getNotNullFixedTurnoverRateCurrencyList() {
        List<CurrencyInfo> currencyList = this.getCurrencyList();
        if(CollectionUtil.isBlank(currencyList)){
            return null;
        }
        return currencyList.stream().filter((CurrencyInfo c)-> c.getFixedTurnoverRate()!=null).collect(Collectors.toList());
    }

    public BigDecimal getConceptBasePeriodSumMarket(Integer conceptCategoryId) {

        if(conceptCategoryId==null){
            return null;
        }
        if("0".equals(redisServer.get(RedisKeysUtils.CURRCY_NOTION_BASE_PERIOD+conceptCategoryId))){
            String sumMarketString = redisServer.get(RedisKeysUtils.CONCEPT_BASE_PERIOD_SUM_MARKET+conceptCategoryId);
            if(MathUtils.isNumeric(sumMarketString)){
                return new BigDecimal(sumMarketString);
            }
        }

        CurrencyConceptCategory searchConceptCategory = new CurrencyConceptCategory();
        searchConceptCategory.setConceptCategory(conceptCategoryId);
        List<CurrencyConceptCategory> currencyConceptCategoryList
                = currencyConceptCategoryMapper.selectByEntityList(searchConceptCategory);
        if(CollectionUtil.isBlank(currencyConceptCategoryList)){
            return null;
        }
        Date maxUpdatetime = null;
        for (CurrencyConceptCategory currencyConceptCategory:currencyConceptCategoryList) {
            Date thisTime = null;
            if(currencyConceptCategory.getUpdateTime()!=null){
                thisTime = currencyConceptCategory.getUpdateTime();
            }else if(currencyConceptCategory.getCreateTime()!=null){
                thisTime = currencyConceptCategory.getCreateTime();
            }
            if(maxUpdatetime==null){
                maxUpdatetime = thisTime;
            }else if(thisTime!=null){
                if(maxUpdatetime.getTime()<thisTime.getTime()){
                    maxUpdatetime = thisTime;
                }
            }
        }
        if(maxUpdatetime==null){
            return null;
        }
        LocalDateTime dateTime = DateUtils.dateToLocalDateTime(maxUpdatetime);
        BigDecimal bigDecimal = new BigDecimal(0);
        /*Date nearDate = currencyInfoHbaseMapper
                .selectAfterNearDate(DateUtils.dateFormatString(maxUpdatetime,DateUtils.format_ymdhms));

        CurrencyInfoHbase searchInfoHbase = new CurrencyInfoHbase();
        searchInfoHbase.setCreateTime(nearDate);*/
        //List<CurrencyInfoHbase> currencyInfoHbases = currencyInfoHbaseMapper.selectByEntityList(searchInfoHbase);
        /*List<CmcCurrencyInfo> cmcInfosByDate = coinMarketCapDataComponent.getCmcInfosByDate(nearDate);
        Map<String, CmcCurrencyInfo> cmcMap = cmcDataCalculateComponent.cmcCurrencyInfoListToMap(cmcInfosByDate);*/
        try{
            for (CurrencyConceptCategory currencyConceptCategory:currencyConceptCategoryList) {
                CurrencyInfo currencyInfo = currencyInfoDao.selectByPrimaryKey(currencyConceptCategory.getCurrencyId());
                if(currencyInfo==null || currencyInfo.getDeleteFlag() || !currencyInfo.getEnableFlag() ){
                    continue;
                }
                Map<String, List<DailyComprehensiveAnalysisInfo>> dailyMap =
                        coinMarketCapDataComponent.getDailyCurrencyInfor(
                                currencyInfo.getCmcId()+"@"+ DateUtils.dateFormatString(maxUpdatetime,DateUtils.format_ymds));
                DailyComprehensiveAnalysisInfo cmcCurrencyInfo = DailyInfoUtils.getNearDailyInfo(dailyMap, dateTime.getHour(), dateTime.getMinute());
                if(cmcCurrencyInfo!=null && MathUtils.isNumeric(cmcCurrencyInfo.getMarketCapCny())){
                    bigDecimal = bigDecimal.add(new BigDecimal(cmcCurrencyInfo.getMarketCapCny()));
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            LogTrace.error(e.getMessage(),e);
        }

        return bigDecimal;
    }
}
